<?php


namespace app\api\controller\v27;


use app\api\controller\v2\Auth;
use app\common\cachemodel\live\LiveAnchorInfo;
use app\common\cachemodel\live\LiveGoodsActivity;
use app\common\cachemodel\live\LiveRecordingInfo;
use app\common\cachemodel\MallGoods;
use app\common\cachemodel\MallGoodsAttr;
use app\common\cachemodel\MallUserAddress;
use app\common\cachemodel\OrdersGoods;
use app\common\cachemodel\OrdersLib;
use app\common\cachemodel\ZlUserVip;
use app\common\lib\exception\ApiException;
use app\common\lib\Orders;
use app\common\lib\PushQueue;
use app\common\lib\SensorsData;
use think\Db;
use think\Log;
use think\response\Json;

/**
 * @version 2.3.0
 * Class MallOrder
 * @package app\api\controller\v20
 */
class MallOrder extends Auth
{
    protected $msg;

    /**
     * 商品确认接口
     * @return Json
     * @throws \Exception
     */
    public function order_check()
    {
        $sid = input('sid/d', 0);
        $liveId = input('live_id/d', 0);
        $liveRecordId = input('live_record_id/d', 0);
        (new LiveRecordingInfo())->checkRecordId($liveId, $liveRecordId);
        $uid = (int)$this->user['id'];

        if (!$sid)
        {
            return show(config('code.error'), '请求异常，参数缺失！');
        }

        $mallGoodAttrInfo = (new MallGoodsAttr())->batGetInfo($sid, ['id', 'name', 'gid', 'status', 'now_price', 'vip_price', 'inventory']);
        if (!$mallGoodAttrInfo)
        {
            return show(config('code.error'), '服务异常，规格不存在！');
        }
        // 属性信息
        $mallGoodAttrInfo = $mallGoodAttrInfo[$sid];

        $goodInfo = current((new MallGoods())->batGetInfo($mallGoodAttrInfo['gid'], ['imgs', 'status', 'name', 'kd_price', 'faraway_kd_price', 'channel_id']));
        if (!$goodInfo)
        {
            return show(config('code.error'), '服务异常！请稍后再试～');
        }

        //获取用户会员信息 判断现在是否是会员并且会员生效
        $userVip = (new ZlUserVip())->getInfoById($uid);
        $isVip = false;
        if ($userVip && $userVip['is_valid'] && $userVip['vip_level'] > 0)
        {
            $isVip = true;
        }

        $goodImgs = explode(',', $goodInfo['imgs']);
        // 默认使用0.2的缩略图
        $img = $goodImgs ? current($goodImgs) . '?x-oss-process=style/scale0.2' : '';

        $inventory = (int)($mallGoodAttrInfo['status'] ? $mallGoodAttrInfo['inventory'] : 0);

        $goodsInfo = [
            'img' => $img,
            'title' => $goodInfo['name'] ?? '',
            'specification' => '规格：' . ($mallGoodAttrInfo['name'] ?? ''),
            'price' => $isVip ? $mallGoodAttrInfo['vip_price'] : $mallGoodAttrInfo['now_price'],
            'tips' => '付款后7天左右发货',
            'kd_price' => $goodInfo['kd_price'],
            'faraway_kd_price' => $goodInfo['faraway_kd_price'],
            'inventory' => $inventory > 0 ? $inventory : 0,
        ];

        // 获取默认收货地址信息
        $addressInfo = (new MallUserAddress())->getDefault($uid);

        $mallGoodAttrInfos = [$mallGoodAttrInfo['id'] => $mallGoodAttrInfo];
        //打折已商品现价为基础,不使用vip价格
        $active_data = [];
        if ($liveId)
        {
            (new LiveGoodsActivity())->getLiveOrderTypeGoods($liveId, 14, $mallGoodAttrInfos);
            if (!empty(current($mallGoodAttrInfos)['live_active']))
            {
                $vipPrice = $goodsInfo['price'] = $mallGoodAttrInfo['now_price'];//若商品有直播活动则显示商品原价
                $active_data = [
                    'name' => current($mallGoodAttrInfos)['live_active']['name'],
                    'discount_price' => current($mallGoodAttrInfos)['live_active']['discount_price'],
                    'type' => 2,
                ];
            }
        }
        $goodsInfo['active_data'] = $active_data;
        $distinctId = $this->request->header('distinct-id', '');
        if ($distinctId)
        {
            #神策打点 66 选择万幸商品规格 MallGoodsSelect
            $supplier_name = Db::table('wechat_backup_07_18_14_43_00.mall_channel')->where('id', $goodInfo['channel_id'])->value('name');
            $sensorsTrackData = [
                'goods_name' => $goodsInfo['title'],// 商品名称
                'goods_price' => $vipPrice ?? $goodsInfo['price'],// 商品单价
                'goods_id' => $mallGoodAttrInfo['gid'],// 商品ID
                'goods_inventory' => $inventory ?: 0,// 商品库存
                'supplier_name' => $supplier_name ?? '',// 供应商名称
                'supplier_id' => (int)$goodInfo['channel_id'],// 供应商ID
                'specification_name' => $mallGoodAttrInfo['name'] ?? '',// 规格样式
                'live_id' => $liveId,
                'live_record_id' => $liveRecordId,
            ];
            SensorsData::track($uid, true, 'MallGoodsSelect', $sensorsTrackData);
        }

        return show(config('code.success'), '请求成功', [
            'address_info' => $addressInfo['address_info'],
            'address_option' => $addressInfo['address_option'],
            'good_info' => $goodsInfo,
        ]);
    }

    /**
     * 实体商品下单接口
     * @return \think\response\Json
     * @throws ApiException
     */
    public function pay_order()
    {
        $param['trade_type'] = input('trade_type/d', 0);//支付方式
        $param['a_id'] = input('a_id/d', 0);//地址id
        $param['sid'] = input('sid/d', 0);//商品规格id
        $param['remark'] = input('remark/s', '');//备注
        $param['num'] = input('num/d', 0);//购买数量
        $param['live_id'] = input('live_id/d', 0);//直播间ID
        $param['live_record_id'] = input('live_record_id/d', 0);
        (new LiveRecordingInfo())->checkRecordId($param['live_id'], $param['live_record_id']);
        $openid = input('param.openid', '');// openid
        $callback_url = input('param.callback_url', '');
        $extend = [];
        //请求参数验证
        $this->checkPayParam($param);
        if ($this->msg)
        {
            return show(config('code.error'), $this->msg);
        }

        //获取地址信息
        $addr = (new MallUserAddress())->getInfoById($param['a_id'], ['uid', 'country', 'province', 'city', 'address_desc', 'phone', 'name', 'is_faraway']);
        if (!$addr || $addr['uid'] != $this->user['id'])
        {
            return show(config('code.error'), '缺少地址信息');
        }
        $mallGoodsAttrModel = new MallGoodsAttr();
        $mallGoodsModel = new MallGoods();
        //获取规格信息
        $spectInfo = current($mallGoodsAttrModel->batGetInfo($param['sid'], ['id', 'name', 'gid', 'now_price', 'vip_price', 'inventory']));//获取商品的规格信息
        if (!$spectInfo)
        {
            return show(config('code.error'), '未知的商品');
        }
        //获取商品信息
        $goodsInfo = current($mallGoodsModel->batGetInfo([$spectInfo['gid']], ['kd_price', 'faraway_kd_price', 'name']));
        //获取商品运费
        if ($addr['is_faraway'])
        {
            $kdPrice = $goodsInfo['faraway_kd_price'];
        } else
        {
            $kdPrice = $goodsInfo['kd_price'];
        }

        //验证商品库存数量
        if ($spectInfo['inventory'] < $param['num'])
        {
            return show(config('code.error'), '当前商品库存不足');
        }
        //打折已商品现价为基础,不使用vip价格
        $spectInfos = [$spectInfo['id'] => $spectInfo];
        (new LiveGoodsActivity())->getLiveOrderTypeGoods($param['live_id'], 14, $spectInfos);
        if (!empty(current($spectInfos)['live_active']))
        {
            $spectInfoTmp = current($spectInfos);
            $resPrice = $spectInfoTmp['live_active']['price'];
            $activeData = [
                $spectInfo['id'] => [
                    'type' => 2,
                    'discount_type' => $spectInfoTmp['live_active']['type'],
                    'attr' => $spectInfoTmp['live_active']['attr'],
                    'ac_id' => $spectInfoTmp['live_active']['id'],
                    'name' => $spectInfoTmp['live_active']['name'],
                    'gname' => $spectInfoTmp['name'],
                    'des' => $spectInfoTmp['live_active']['des'],
                    'price' => $spectInfoTmp['live_active']['price'],
                    'discount_price' => $spectInfoTmp['live_active']['discount_price'],
                    'num' => $param['num'],
                ]
            ];
            $extend['new_active'] = $activeData;
        }

        //判读当前用户是否是vip
        $userVip = (new ZlUserVip())->getInfoById($this->user['id']);
        if ($userVip && $userVip['is_valid'] && empty($activeData))
        {
            $onePrice = $spectInfo['vip_price'];
            $price = $spectInfo['vip_price'] * $param['num'] + $kdPrice;
        } else
        {
            $onePrice = $spectInfo['now_price'];
            $price = $spectInfo['now_price'] * $param['num'] + $kdPrice;
        }

        //订单商品信息拓展
        $extend['goods_info'] = [
            $spectInfo['id'] => [
                'type' => 14,
                'name' => $spectInfo['name'],
                'price' => $onePrice,
                'num' => $param['num'],
            ]
        ];

        if (isset($resPrice))
        {
            $price = $resPrice * $param['num'] + $kdPrice;
        }

        // 生成唯一订单号  011806192149570386 01=>生时校正 02=>运势 03=>占星地图，04=>占星视频，05=>本命预测，06=>vip，07=>准币,08=>商场，09=>定制报告
        $out_trade_no = str_pad(8, 2, '0', STR_PAD_LEFT) . date('YmdHis') . str_pad(random_int(1, 9999), 4, '0', STR_PAD_LEFT);

        //获取当前商品的支付账号
        $account = OrdersLib::getOrderAccountType($out_trade_no, $param['trade_type']);

        $extend['mall'] = [
            'address' => $addr['country'] . '，' . $addr['province'] . '，' . $addr['city'] . '，' . $addr['address_desc'],
            'phone' => $addr['phone'],
            'name' => $addr['name'],
            'is_faraway' => $addr['is_faraway'],
            'kd_id' => '',
            'kd_name' => '',
            'kd_price' => $kdPrice,
            'num' => $param['num'],
            'mall_gid' => $spectInfo['gid'],
            'remark' => $param['remark']
        ];
        if ($param['live_id'])
        {
            $liveInfo = (new LiveAnchorInfo())->getInfoById($param['live_id'], ['live_id', 'name', 'avatar']);
            $liveInfo['live_record_id'] = (new LiveRecordingInfo())->getNewestRecord($param['live_id']);
            $env_type = 8;//直播间渠道
            $liveInfo['gname'] = $goodsInfo['name'] . '-' . $spectInfo['name'];
            $liveInfo['total_amount'] = $price;
            $extend['live_info'] = $liveInfo;
        }

        //订单入库
        $insert = [
            'order_type' => 14,
            'uid' => $this->user['id'],
            'gid' => $param['sid'],
            'order_id' => $out_trade_no,
            'reid' => 0,
            'fid' => 0,
            'trade_type' => $param['trade_type'],
            'total_amount' => $price,
            'create_time' => time(),
            'status' => 0,
            'account' => $account['account'],
            'env_type' => $env_type ?? 1,
            'extend' => json_encode($extend, true)
        ];

        // 生成订单到数据库
        Db::startTrans();
        try
        {
            $orderCacheModel = new \app\common\cachemodel\Orders();
            $oid = $orderCacheModel->SaveData($insert);
            //检测订单关闭入队
            PushQueue::CloseOrder($out_trade_no);
            //中间表添加数据
            $this->addInfo($oid, [$param['sid']], 0);
            //商城库存处理
            $mallGoodsAttrModel->where('id', $param['sid'])->setDec('inventory', $param['num']);
            $mallGoodsAttrModel->UpdateCache($param['sid']);
            Db::commit();
        }
        catch (\Exception $e)
        {
            Db::rollback();
            Log::write('商城下单失败：' . $e->getMessage(), 'error');
            throw new ApiException('下单失败,请重新操作');
        }
        //支付订单
        $arr = (new Orders())->unifyPayOrder([
            'oid' => $oid,
            'trade_type' => $param['trade_type'],
            'total_amount' => $price,
            'pay_des' => '准了 - ' . $goodsInfo['name'],
            'order_id' => $out_trade_no,
            'openid' => $openid,
            'callback_url' => $callback_url,
            'order_type' => 14
        ], 1);
        $distinctId = $this->request->header('distinct-id', '');
        if ($distinctId)
        {
            #神策打点 68 商品确认支付 MallGoodsBuyConfirm
            (new \app\common\service\Orders())->getSensorsTrackData($arr['data']['order_id'], 'buy_confirm');
        }

//        $arr['data']['skuId'] = 'apple_pay_' . $param['sid'];
        return show(config('code.success'), '下单成功', $arr['data']);
    }

    /**
     * 添加订单中间表数据
     * @param int $oid
     * @param array $gids
     * @param int $rid
     * @return bool
     */
    private function addInfo($oid, $gids, $rid)
    {
        $array = [];
        foreach ($gids as $k => $v)
        {
            $array[] = [
                'gid' => $v,
                'oid' => $oid,
                'rid' => $rid
            ];
        }
        //中间表
        (new OrdersGoods())->SaveData($array);
        return true;
    }

    /**
     * 验证下单请求参数
     * @param array $param
     * @return string
     */
    private function checkPayParam($param)
    {
        if (!in_array($param['trade_type'], [1, 2], false))
        {
            return $this->msg = '当前支付方式不支持';
        }
        if (!$param['a_id'])
        {
            return $this->msg = '缺少地址信息';
        }
        if (!$param['sid'])
        {
            return $this->msg = '商品不存在';
        }
        if (mb_strlen($param['remark']) > 150)
        {
            return $this->msg = '备注信息最多150个字';
        }
        if ($param['num'] <= 0)
        {
            return $this->msg = '请选择商品数量';
        }
        return $this->msg = '';
    }

    /**
     * 实体商品订单详情接口
     * @return Json
     * @throws \Exception
     */
    public function order()
    {
        $order_id = input('order_id', '');
        if (!$order_id)
        {
            return show(config('code.error'), '订单不存在');
        }
        $ordersModel = new \app\common\cachemodel\Orders();
        $orders = $ordersModel->getInfoById($order_id);
        if (!$orders || $orders['uid'] != $this->user['id'])
        {
            return show(config('code.error'), '数据不存在');
        }
        if ($orders['is_del'] == 1)
        {
            return show(config('code.error'), '数据已删除');
        }
        $extend = $orders['extend'] ? json_decode($orders['extend'], true) : [];
        $orders = $ordersModel->ordersDetail($orders);
        if (!empty($extend['new_active']))
        {
            $active = current($extend['new_active']);
            $active_data = [
                'name' => $active['name'],
                'price' => $active['discount_price'] * $active['num'],
                'type' => $active['type']
            ];
        }
        $goodsInfo = $ordersModel->MallRead($orders);
        $order_data = $this->getMallRead($orders, $extend, $goodsInfo['extend']);
        if ($goodsInfo['extend']['is_faraway'])
        {
            $kdPrice = '¥' . $goodsInfo['extend']['kd_price'];
            $kdName = '偏远地区运费';
        } else
        {
            $kdPrice = '¥0.00';
            $kdName = '快递 包邮';
        }
        //判读当前用户是否是vip
        $userVip = (new ZlUserVip())->getInfoById($this->user['id']);
        if ($userVip && $userVip['is_valid'] && empty($active_data))
        {
            $price = $goodsInfo['spec_info']['vip_price'];
        } else
        {
            $price = $goodsInfo['spec_info']['now_price'];
        }
        $arr = [
            'status' => (int)$orders['status'],
            'des' => $orders['des'] ?: $orders['status_des'],
            'address_data' => [
                'name' => $goodsInfo['extend']['name'],
                'phone' => $goodsInfo['extend']['phone'],
                'address' => str_replace('，', '', $goodsInfo['extend']['address'])
            ],
            'goods_data' => [
                0 => [
                    'gid' => (int)$goodsInfo['goods_data']['id'],
                    'sid' => (int)$goodsInfo['spec_info']['id'],
                    'img' => $goodsInfo['spec_info']['img'] ? $goodsInfo['spec_info']['img'] . '?x-oss-process=style/scale0.2' : '',
                    'title' => $goodsInfo['goods_data']['name'],
                    'specification' => '规格：' . $goodsInfo['spec_info']['name'],
                    'price' => $price,
                    'num' => $goodsInfo['extend']['num'],
                ]
            ],
            'kd_data' => [
                'name' => $kdName,
                'price' => $kdPrice
            ],
            'order_data' => $order_data,
            'btn_data' => $this->getBtnData((int)$orders['status'], isset($goodsInfo['extend']['kd_id']) && !empty($goodsInfo['extend']['kd_id'])),
            'total_amount' => $orders['total_amount'],
            'time_remaining' => $orders['time_remaining'] ?? 0,
            'active_data' => $active_data ?? null
        ];

        return show(config('code.success'), '获取成功', $arr);
    }

    /**
     * 获取按钮信息
     * @param int $status
     * @param bool $isSendKD 是否发送了快递
     * @return object
     */
    private function getBtnData(int $status, bool $isSendKD)
    {
        switch ($status)
        {
            case 0: // 未支付
                $btnData = [
                    'top' => null,
                    'middle' => null,
                    'bottom' => [
                        'name' => '立即支付',
                        'type' => 2
                    ],
                ];
                break;
            case 1: // 待发货
                $btnData = [
                    'top' => null,
                    'middle' => null,
                    'bottom' => [
                        'name' => '再次购买',
                        'type' => 6
                    ],
                ];
                break;
            case 2: // 交易关闭
                $btnData = [
                    'top' => [
                        'name' => '删除订单',
                        'type' => 1
                    ],
                    'middle' => null,
                    'bottom' => [
                        'name' => '再次购买',
                        'type' => 6
                    ],
                ];
                break;
            case 3: // 退款成功
                $btnData = [
                    'top' => [
                        'name' => '删除订单',
                        'type' => 1
                    ],
                    'middle' => $isSendKD ? [
                        'name' => '查看物流',
                        'type' => 7
                    ] : null,
                    'bottom' => [
                        'name' => '再次购买',
                        'type' => 6
                    ],
                ];
                break;
            case 4: // 已完成
                $btnData = [
                    'top' => [
                        'name' => '删除订单',
                        'type' => 1
                    ],
                    'middle' => [
                        'name' => '查看物流',
                        'type' => 7
                    ],
                    'bottom' => [
                        'name' => '再次购买',
                        'type' => 6
                    ],
                ];
                break;
            case 5: // 等待收货
                $btnData = [
                    'top' => [
                        'name' => '再次购买',
                        'type' => 6
                    ],
                    'middle' => [
                        'name' => '查看物流',
                        'type' => 7
                    ],
                    'bottom' => [
                        'name' => '确认收货',
                        'type' => 8
                    ],
                ];
                break;
            default:
                $btnData = (object)[];
        }
        return $btnData;
    }

    /**
     * 获取商城详情信息
     * @param $orders
     * @param $extend
     * @param $mallExtend
     * @return array|array[]
     */
    private function getMallRead($orders, $extend, $mallExtend)
    {
        //获取快递公司
        $kdName = config('kd')[strtoupper($mallExtend['kd_name'])] ?? $mallExtend['kd_name'];
        switch ($orders['status'])
        {
            case 0:
            case 2:
                $data = [
                    0 => [
                        'name' => '订单编号',
                        'value' => $orders['order_id'],
                        'is_copy' => 1
                    ],
                    1 => [
                        'name' => '下单时间',
                        'value' => dateModify('Y-m-d H:i:s', $orders['create_time']),
                        'is_copy' => 0
                    ],
                ];
                break;
            case 1:
                $data = [
                    0 => [
                        'name' => '订单编号',
                        'value' => $orders['order_id'],
                        'is_copy' => 1
                    ],
                    1 => [
                        'name' => '下单时间',
                        'value' => dateModify('Y-m-d H:i:s', $orders['create_time']),
                        'is_copy' => 0
                    ],
                    2 => [
                        'name' => '支付方式',
                        'value' => $orders['trade_type'] == 1 ? '支付宝' : '微信',
                        'is_copy' => 0
                    ],
                    3 => [
                        'name' => '支付时间',
                        'value' => dateModify('Y-m-d H:i:s', $orders['pay_time']),
                        'is_copy' => 0
                    ],
                ];
                break;
            case 3:
            case 4:
            case 5:
                $data = [
                    0 => [
                        'name' => '订单编号',
                        'value' => $orders['order_id'],
                        'is_copy' => 1
                    ],
                    1 => [
                        'name' => '下单时间',
                        'value' => dateModify('Y-m-d H:i:s', $orders['create_time']),
                        'is_copy' => 0
                    ],
                    2 => [
                        'name' => '支付方式',
                        'value' => $orders['trade_type'] == 1 ? '支付宝' : '微信',
                        'is_copy' => 0
                    ],
                    3 => [
                        'name' => '支付时间',
                        'value' => dateModify('Y-m-d H:i:s', $orders['pay_time']),
                        'is_copy' => 0
                    ],
                ];
                if ($kdName)
                {
                    array_unshift($data, [
                        'name' => $kdName,
                        'value' => $mallExtend['kd_id'],
                        'is_copy' => 1
                    ]);
                }
                break;
            default :
                $data = [];
                break;
        }
        if (!empty($extend['live_info']))
        {
            $data[] = [
                'name' => '下单直播间',
                'value' => $extend['live_info']['name'],
                'is_copy' => 0
            ];
        }
        if ((int)$orders['status'] === 3)
        {
            $data[] = [
                'name' => '退款原因',
                'value' => $extend['mall']['reason'] ?? '',
                'is_copy' => 0
            ];
            $data[] = [
                'name' => '退款金额',
                'value' => $extend['mall']['refund_amount'] ?? $orders['total_amount'],
                'is_copy' => 0
            ];
            $data[] = [
                'name' => '退款时间',
                'value' => $extend['mall']['refund_time'] ?? '',
                'is_copy' => 0
            ];
        }
        return $data;
    }
}
